using System;
using System.Collections.Generic;
using System.Text;
using ALib;
using NUnit.Framework;
using WorldClock;

namespace TradingPlatform
{
    public class UtcConverter
    {
        private readonly TimeZoneInformation _tradingPlatformTimeZoneInformation;
        private readonly TimeZoneInformation _exchangeTimeZoneInformation;
        public UtcConverter(int tradingPlatformTimeZoneIndex, int exchangeTimeZoneIndex)
        {
            GoodValue.Assert(0 <= tradingPlatformTimeZoneIndex && tradingPlatformTimeZoneIndex <= 600);
            GoodValue.Assert(0 <= exchangeTimeZoneIndex && exchangeTimeZoneIndex <= 600);
            _tradingPlatformTimeZoneInformation = TimeZoneInformation.FromIndex(tradingPlatformTimeZoneIndex);
            _exchangeTimeZoneInformation = TimeZoneInformation.FromIndex(exchangeTimeZoneIndex);
        }

        public DateTime TradingPlatformTimeToUtc(DateTime tradingPlatformTime)
        {
            DateTime result = _tradingPlatformTimeZoneInformation.ToUniversalTime(tradingPlatformTime);
            return result;
        }

        public DateTime ExchangeTimeToUtc(DateTime exchangeTime)
        {
            DateTime result = _exchangeTimeZoneInformation.ToUniversalTime(exchangeTime);
            return result;
        }

        public DateTime UtcToTradingPlatformTime(DateTime utc)
        {
            DateTime result = _tradingPlatformTimeZoneInformation.ToLocalTime(utc);
            return result;
        }

        public DateTime UtcToExchangeTime(DateTime utc)
        {
            DateTime result = _exchangeTimeZoneInformation.ToLocalTime(utc);
            return result;
        }

        public DateTime ExchangeTimeToTradingPlatformTime(DateTime exchangeTime)
        {
            DateTime utc = ExchangeTimeToUtc(exchangeTime);
            DateTime result = UtcToTradingPlatformTime(utc);
            return result;
        }

        public DateTime TradingPlatformTimeToExchangeTime(DateTime tradingPlatformTime)
        {
            DateTime utc = TradingPlatformTimeToUtc(tradingPlatformTime);
            DateTime result = UtcToExchangeTime(utc);
            return result;
        }

        private static readonly Dictionary<string, UtcConverter> _utcConverterCache = new Dictionary<string, UtcConverter>();
        public static DateTime TradingPlatformTimeToExchangeTime(int tradingPlatformTimeZoneIndex, int exchangeTimeZoneIndex, DateTime tradingPlatformTime)
        {
            string utcConverterName = string.Format(@"{0},{1}", tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex);
            if (!_utcConverterCache.ContainsKey(utcConverterName))
            {
                _utcConverterCache.Add(utcConverterName, new UtcConverter(tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex));
            }
            DateTime result = _utcConverterCache[utcConverterName].TradingPlatformTimeToExchangeTime(tradingPlatformTime);
            return result;
        }

        public static DateTime TradingExchangeTimeToPlatformTime(int tradingPlatformTimeZoneIndex, int exchangeTimeZoneIndex, DateTime exchangeTime)
        {
            string utcConverterName = string.Format(@"{0},{1}", tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex);
            if (!_utcConverterCache.ContainsKey(utcConverterName))
            {
                _utcConverterCache.Add(utcConverterName, new UtcConverter(tradingPlatformTimeZoneIndex, exchangeTimeZoneIndex));
            }
            DateTime result = _utcConverterCache[utcConverterName].ExchangeTimeToTradingPlatformTime(exchangeTime);
            return result;
        }
    }
}
